package com.pureland.demo.controller;

import com.pureland.common.entity.R;
import com.pureland.storage.StorageTemplate;
import com.pureland.storage.bean.Storage;
import com.pureland.storage.bean.StorageResult;
import com.pureland.storage.properties.StorageProperties;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;

/**
 * @projectName: pureland_cloud
 * @className: com.pureland.demo.controller.MinIOController
 * @description: MinIO对象存储控制器
 * @author: tong.li
 * @createTime: 2020/10/19 16:53
 * @version: v1.0
 * @copyright: 版权所有 李彤 © 2020
 */
@RestController
public class MinIOController {

    private static final Logger log = LoggerFactory.getLogger(MinIOController.class);

    @Autowired
    private StorageTemplate storageTemplate;

    @Autowired
    private StorageProperties storageProperties;

    /**
     * 通过Web接口加载本地文件上传到MinIO对象存储服务器
     * @return
     */
    @PostMapping("/uploadForWeb")
    public R uploadForWeb(MultipartFile file) {

        // 源文件名称
        String originalFilename = file.getOriginalFilename();
        Storage storage = Storage.builder()
                .randomName(false)
                .originName(originalFilename)
                .bucketName(this.storageProperties.getMinio().getBucket())
                .build();
        StorageResult storageResult = null;
        try {
            storageResult = storageTemplate.upload(storage, file.getInputStream(), file.getContentType(),file.getSize());
        } catch (IOException e) {
            return R.fail("本地文件上传失败!");
        }
        return R.ok(storageResult);
    }


    /**
     * 根据本地地址文件上传到MinIO对象存储服务器
     * @return
     */
    @PostMapping("/uploadForLocal")
    public R uploadForLocal(String filePath) {
        File file = new File(filePath);
        // 源文件名称
        String originalFilename = file.getName();
        Storage storage = Storage.builder()
                .randomName(false)
                .originName(originalFilename)
                .bucketName(this.storageProperties.getMinio().getBucket())
                .build();
        StorageResult storageResult = null;
        try {
            storageResult = storageTemplate.upload(storage,file,null);
        } catch (Exception e) {
            return R.fail("本地文件上传失败!");
        }
        return R.ok(storageResult);
    }


    /**
     * 根据网络地址文件上传到MinIO对象存储服务器
     * @return
     */
    @PostMapping("/uploadForURL")
    public R uploadForURL(String fileName,String url) {
        Storage storage = Storage.builder()
                .randomName(false)
                .originName(fileName)
                .bucketName(this.storageProperties.getMinio().getBucket())
                .build();
        StorageResult upload = storageTemplate.upload(storage, url,null);
        return R.ok(upload);
    }



    /**
     * 根据字节上传到MinIO对象存储服务器
     *  适合RPC远程调用传送二进制数据
     * @return
     */
    @PostMapping("/uploadForByte")
    public R uploadForByte(MultipartFile file) throws IOException {
        Storage storage = Storage.builder()
                .randomName(false)
                .originName(file.getOriginalFilename())
                .bucketName(this.storageProperties.getMinio().getBucket())
                .build();
        StorageResult upload = storageTemplate.upload(storage,file.getBytes());
        return R.ok(upload);
    }


    /**
     * 根据流对象进行下载
     * @return
     */
    @GetMapping("/download")
    public void uploadForByte(HttpServletResponse response,String fileName) throws IOException {
        OutputStream out = response.getOutputStream();
        InputStream is = null;
        try {
            is = this.storageTemplate.getObjectStream(this.storageProperties.getMinio().getBucket(), fileName);
            response.setCharacterEncoding("utf-8");
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            response.addHeader("Content-Disposition", "attachment; filename="
                    + URLEncoder.encode(fileName, "UTF-8"));
            response.addHeader("Pragma", "no-cache");
            response.addHeader("Expires", "0");
            response.addHeader("Last-Modified", LocalDateTime.now().toString());
            response.addHeader("ETag", String.valueOf(System.currentTimeMillis()));
            IOUtils.copy(is,out);
            out.flush();
        } catch (IOException e) {
            log.error("download error",e);
        } finally {
            // 关闭输入流
            try {
                IOUtils.closeQuietly(is);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 关闭响应流
            try {
                IOUtils.closeQuietly(out);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }



}
